﻿/*****************************************介绍*****************************************
 * 作者：Ywh
 * 创建时间：2023-04-14　02:22:13
 * 功能：单个对象池
**************************************************************************************/

using System.Collections.Generic;
using UnityEngine;

namespace Game.Framework
{
    public class ObjectPool
    {
        private Transform m_Parent;
        private GameObject m_Item;
        private Stack<GameObject> m_Pool;
        private int m_Capacity;

        /// <summary>该种方式构建对象池，每次创建Item对象的实例</summary>
        /// <param name="name">对象池的名称</param>
        /// <param name="item">需要创建的对象</param>
        /// <param name="poolRoot">对象池的根节点</param>
        /// <param name="capacity">对象池的容量</param>
        public ObjectPool(string name, GameObject item, Transform poolRoot, int capacity = 5)
        {
            m_Item = item;
            Init(name, poolRoot, capacity);
        }

        private void Init(string name, Transform poolRoot, int capacity = 5)
        {
            m_Parent = new GameObject(name).transform;
            m_Parent.parent = poolRoot;
            m_Pool = new Stack<GameObject>(capacity);
            m_Item.SetActive(false);
            m_Capacity = capacity;
        }

        public void Delete(GameObject target)
        {
            if (m_Pool.Count < m_Capacity)
            {
                target.SetActive(false);
                target.transform.SetParent(m_Parent);
                m_Pool.Push(target);
            }
            else
            {
                Object.Destroy(target);
            }
        }

        public GameObject Get()
        {
            if (!m_Pool.TryPop(out GameObject result))
            {
                result = Object.Instantiate(m_Item, m_Parent);
            }
            result.SetActive(true);
            result.transform.SetParent(null);

            return result;
        }

        public void Clear()
        {
            while (m_Pool.TryPop(out GameObject obj))
            {
                if (obj)
                    Object.Destroy(obj);
            }
            if (m_Parent)
                Object.Destroy(m_Parent.gameObject);
            m_Pool = null;
            m_Item = null;
        }
    }
}
